package com.sisgesbyte.services.proyeccion;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.inject.Inject;
import com.sisgesbyte.common.ConstModAdministracion;
import com.sisgesbyte.common.ConstProyeccion;
import com.sisgesbyte.common.ConstantesInternasSistema;
import com.sisgesbyte.common.Validaciones;
import com.sisgesbyte.dao.beanDao.FiltrosBean;
import com.sisgesbyte.dao.beanDao.FiltrosSQLBean;
import com.sisgesbyte.dao.proyeccion.MantBandaProyeccionDao;
import com.sisgesbyte.dao.proyeccion.MantProyeccionCatClienteDetDao;
import com.sisgesbyte.dao.proyeccion.MantProyeccionCategoriaClienteDao;
import com.sisgesbyte.dao.ventas.ConsultaVentasDao;
import com.sisgesbyte.data.entity.proyeccion.BandaProyeccionEntity;
import com.sisgesbyte.data.entity.proyeccion.ProyeccionCatClienteDetEntity;
import com.sisgesbyte.data.entity.proyeccion.ProyeccionCategoriaClienteEntity;
import com.sisgesbyte.data.entity.ventas.VentasEntity;
import com.sisgesbyte.services.administracion.MantenimientoCategoriaCliente;
import com.sisgesbyte.services.administracion.bean.CategoriaClienteBean;
import com.sisgesbyte.services.administracion.bean.CategoriaClienteListaRes;
import com.sisgesbyte.services.proyeccion.bean.AvanceProyCategoriaClienteResponse;
import com.sisgesbyte.services.proyeccion.bean.AvanceProyeccionProductResponse;
import com.sisgesbyte.services.proyeccion.bean.AvanceVentaProductosBean;
import com.sisgesbyte.services.proyeccion.bean.FiltrosProyeccionCanalBean;
import com.sisgesbyte.services.proyeccion.bean.ProyCategoriaClienteBean;

@Stateless
public class ProyeccionCategoriaClienteServiceImpl implements ProyeccionCategoriaClienteService {

	@EJB
	private MantenimientoCategoriaCliente mantenimientoCategoriaCliente;
	@EJB
	private MantProyeccionCategoriaClienteDao mantProyeccionCategoriaClienteDao;
	@EJB
	private MantProyeccionCatClienteDetDao mantProyeccionCatClienteDetDao;
	@EJB
	private MantBandaProyeccionDao mantBandaProyeccionDao;
	@EJB
	private ConsultaVentasDao consultaVentasDao;
	@Inject
	private Validaciones validaciones;
	
	@Override
	public AvanceProyCategoriaClienteResponse listaAvanceCategoriaCliente( String codTransaccion,int idZona, int idPeriodo, int idCanal) {
		
		String mensajeTransaccionMetodo = "[listaAvanceCategoriaCliente idTx=" + codTransaccion + "] - ";
		AvanceProyCategoriaClienteResponse response = new AvanceProyCategoriaClienteResponse();
		CategoriaClienteListaRes listaCategoriaCliente =null;
		try{
			System.out.println("//1.- obtenemos lista categoria clientes");
			 FiltrosSQLBean filtro= new FiltrosSQLBean();
			 List<FiltrosBean> listaFiltros = new ArrayList<FiltrosBean>();
			 List<Object> valores = new ArrayList<Object>();
			
			 //filtro de solo activos
			 FiltrosBean filtroActivo = new FiltrosBean();
			 List<String> camposActivo = new ArrayList<String>();
			 camposActivo.add("active");
			 filtroActivo.setCampos(camposActivo);
			 filtroActivo.setOperador("=");
			 listaFiltros.add(filtroActivo);
			 valores.add(true);
			 
			 //filtro por idCanal
			 if(idCanal >0){
				 FiltrosBean filtroCanal = new FiltrosBean();
				 List<String> camposCanal = new ArrayList<String>();
				 camposCanal.add("id");
				 filtroCanal.setCampos(camposCanal);
				 filtroCanal.setOperador("=");
				 listaFiltros.add(filtroCanal);
				 valores.add(idCanal);
			 }

			 filtro.setListaFiltros(listaFiltros);
			 filtro.setListaValores(valores);
			//1.- obtenemos lista categoria clientes
			listaCategoriaCliente = mantenimientoCategoriaCliente.listaCategoriaCliente(codTransaccion, filtro);
			System.out.println("listaCategoriaCliente: " + listaCategoriaCliente.getCodigoRespuesta());
			if(!listaCategoriaCliente.getCodigoRespuesta().equalsIgnoreCase(ConstantesInternasSistema.CODIGO_EXITO)){
				System.out.println(mensajeTransaccionMetodo + "No se encontraron Datos para listar la categoria de clientes");
				response.setCodigoRespuesta(ConstProyeccion.PROYECCION_LISTAR_COD_IDF);
				response.setMensajeRespuesta(ConstProyeccion.PROYECCION_LISTAR_MSJ_IDF);
				return response;
			}
			
		}catch(Exception e){
			System.out.println(mensajeTransaccionMetodo + "Hubo un error al listar categorias de cliente de  BD " + e);
			response.setCodigoRespuesta(ConstProyeccion.PROYECCION_LISTAR_COD_IDT);
			response.setMensajeRespuesta(ConstProyeccion.PROYECCION_LISTAR_MSJ_IDT);
			return response;
		}
		
		List<ProyeccionCategoriaClienteEntity> proyeccionCatCliente = null;
		try{
			 FiltrosSQLBean filtro= new FiltrosSQLBean();
			 List<FiltrosBean> listaFiltros = new ArrayList<FiltrosBean>();
			 List<Object> valores = new ArrayList<Object>();
			 
			 if(idZona > 0){
				 //filtro por zona
				 FiltrosBean filtroZona = new FiltrosBean();
				 List<String> camposZona = new ArrayList<String>();
				 camposZona.add("pcc.zona_id");
				 filtroZona.setCampos(camposZona);
				 filtroZona.setOperador("=");
				 listaFiltros.add(filtroZona);
				 valores.add(idZona);
			 }
			 if(idCanal > 0){
				 //filtro por canal 
				 FiltrosBean filtroCanal = new FiltrosBean();
				 List<String> camposCanal = new ArrayList<String>();
				 camposCanal.add("pcc.categoria_cliente_id");
				 filtroCanal.setCampos(camposCanal);
				 filtroCanal.setOperador("=");
				 listaFiltros.add(filtroCanal);
				 valores.add(idCanal);
			 }
			 filtro.setListaFiltros(listaFiltros);
			 filtro.setListaValores(valores);
			
			 System.out.println("//2.-Obtenemos la lista de proyecciones de categoria de cliente");
			//2.-Obtenemos la lista de proyecciones de categoria de cliente
			proyeccionCatCliente = mantProyeccionCategoriaClienteDao.listaProyeccionCategoriaCliente(filtro);
			if(!(proyeccionCatCliente.size() > 0)){
				System.out.println(mensajeTransaccionMetodo + "No se encontraron Datos para listar proyecciones de categoria de clientes");
				response.setCodigoRespuesta(ConstProyeccion.PROYECCION_LISTAR_COD_IDF);
				response.setMensajeRespuesta(ConstProyeccion.PROYECCION_LISTAR_MSJ_IDF);
				return response;
			}
		}catch(Exception e){
			System.out.println(mensajeTransaccionMetodo + "Hubo un error al listar las proyecciones de categorias de cliente de  BD " + e);
			response.setCodigoRespuesta(ConstProyeccion.PROYECCION_LISTAR_COD_IDT);
			response.setMensajeRespuesta(ConstProyeccion.PROYECCION_LISTAR_MSJ_IDT);
			return response;
		}
		
		List<VentasEntity> listaVentasPorZona = null;
		try{
			FiltrosSQLBean filtro= new FiltrosSQLBean();
			 List<FiltrosBean> listaFiltros = new ArrayList<FiltrosBean>();
			 List<Object> valores = new ArrayList<Object>();
			 
			 if(idZona > 0){
				 //filtro por zona
				 FiltrosBean filtroZona = new FiltrosBean();
				 List<String> camposZona = new ArrayList<String>();
				 camposZona.add("zona_id");
				 filtroZona.setCampos(camposZona);
				 filtroZona.setOperador("=");
				 listaFiltros.add(filtroZona);
				 valores.add(idZona);
			 }
			 if(idCanal > 0){
				 //filtro por canal 
				 FiltrosBean filtroCanal = new FiltrosBean();
				 List<String> camposCanal = new ArrayList<String>();
				 camposCanal.add("categoria_cliente_id");
				 filtroCanal.setCampos(camposCanal);
				 filtroCanal.setOperador("=");
				 listaFiltros.add(filtroCanal);
				 valores.add(idCanal);
			 }
			 filtro.setListaFiltros(listaFiltros);
			 filtro.setListaValores(valores);
			 System.out.println("//3.- Capturamos la lista de ventas por zona");
			//3.- Capturamos la lista de ventas por zona
			listaVentasPorZona = consultaVentasDao.listaVentasDetalle(filtro);
			
		}catch(Exception e){
			System.out.println(mensajeTransaccionMetodo + "Hubo un error en BD al lista de ventas por Zona  " + e);
			response.setCodigoRespuesta(ConstProyeccion.PROYECCION_LISTAR_COD_IDT);
			response.setMensajeRespuesta(ConstProyeccion.PROYECCION_LISTAR_MSJ_IDT);
		}
		
		List<ProyCategoriaClienteBean> listaAvanceCatCliente = new ArrayList<ProyCategoriaClienteBean>(); 
		for(CategoriaClienteBean ls : listaCategoriaCliente.getListaCategoriaCliente()){
			ProyCategoriaClienteBean beanAvance = new ProyCategoriaClienteBean();
			String bandaGeneral = validaciones.validarCamposString(ls.getCodigoBanda());
			String bandaPeriodo ="";
			BigDecimal proyeccionTotal = BigDecimal.ZERO;
			BigDecimal proyeccionPeriodo = BigDecimal.ZERO;
			boolean encontro = false;
			for(ProyeccionCategoriaClienteEntity lista : proyeccionCatCliente){
				if(lista.getCategoria_cliente_id() == ls.getId()){
					encontro=true;
					proyeccionTotal = proyeccionTotal.add(lista.getMonto_proyectado());
				}
				
				if(lista.getPeriodo_id()==idPeriodo && lista.getCategoria_cliente_id()==ls.getId()){
					proyeccionPeriodo = proyeccionPeriodo.add(lista.getMonto_proyectado());
					bandaPeriodo = lista.getBanda_periodo();
				}
			}
			if(encontro){
				BigDecimal ventaTotal = BigDecimal.ZERO;
				BigDecimal ventaPeriodo = BigDecimal.ZERO;
				for(VentasEntity venta : listaVentasPorZona){
					if(venta.getCategoria_cliente_id()==ls.getId()){
						ventaTotal = ventaTotal.add(venta.getTotal());
					}
					if(venta.getCategoria_cliente_id()==ls.getId() && venta.getPeriodo_id()==idPeriodo){
						ventaPeriodo = ventaPeriodo.add(venta.getTotal());
					}
				}
				
				BigDecimal porcentajeAvanceGeneral= BigDecimal.ZERO;
				BigDecimal porcentajeAvancePeriodo = BigDecimal.ZERO;
				
				try{
					porcentajeAvanceGeneral = ventaTotal.divide(proyeccionTotal,4, RoundingMode.CEILING);
				}catch(Exception e){
					System.out.println("Error al obtener  porcentajeAvanceGeneral " + e);
					porcentajeAvanceGeneral= BigDecimal.ZERO;
				}
				
				try{
					porcentajeAvancePeriodo = ventaPeriodo.divide(proyeccionPeriodo,4, RoundingMode.CEILING);
				}catch(Exception e){
					System.out.println("Error al obtener  porcentajeAvancePeriodo " + e);
					porcentajeAvancePeriodo = BigDecimal.ZERO;
				}
				//obtenemos el color de la banda General
				String colorbandaGeneral = colorBanda(bandaGeneral,porcentajeAvanceGeneral,1);
				String colorbandaPeriodo = colorBanda(bandaPeriodo,porcentajeAvancePeriodo,1);
				
				beanAvance.setIdCategoriaCliente(ls.getId());
				beanAvance.setCategoriaCliente(ls.getCategoria());
				beanAvance.setAvanceMontoGeneral(ventaTotal);
				beanAvance.setAvanceMontoPeriodo(ventaPeriodo);
				beanAvance.setAvancePorcentajeGeneral(porcentajeAvanceGeneral);
				beanAvance.setAvancePorcentajePeriodo(porcentajeAvancePeriodo);
				beanAvance.setColorBandaGeneral(colorbandaGeneral);
				beanAvance.setColorBandaPeriodo(colorbandaPeriodo);
				beanAvance.setProyeccionMontoGeneral(proyeccionTotal);
				beanAvance.setProyeccionMontoPeriodo(proyeccionPeriodo);
				listaAvanceCatCliente.add(beanAvance);
			}
		}
		response.setListaProyeccionCategoriaClientes(listaAvanceCatCliente);
		response.setCodigoRespuesta(ConstantesInternasSistema.CODIGO_EXITO);
		response.setMensajeRespuesta(ConstantesInternasSistema.MENSAJE_EXITO);
		return response;
	}

	public String colorBanda(String codBanda,BigDecimal porcentaje, int tipoColor){
		String color ="";
			try{
				
			List<BandaProyeccionEntity> listaBandas = null;
			 try{
				 FiltrosSQLBean cadenaFiltros = new FiltrosSQLBean();
				 List<FiltrosBean> listaFiltros = new ArrayList<FiltrosBean>();
				 FiltrosBean filtroCampos = new FiltrosBean();
				 List<String> campos = new ArrayList<String>();
				 campos.add("codigo");
				 filtroCampos.setCampos(campos);
				 filtroCampos.setOperador("=");
				 listaFiltros.add(filtroCampos);
				 List<Object> valores = new ArrayList<Object>();
				 valores.add(codBanda);
				 cadenaFiltros.setListaFiltros(listaFiltros);
				 cadenaFiltros.setListaValores(valores);
				 listaBandas = mantBandaProyeccionDao.listaBandasProyeccion(cadenaFiltros);
			}catch(Exception e){
				System.out.println("Error al Obtener las bandas: " + e);
			}
			 List<BigDecimal> bandas = new ArrayList<BigDecimal>();
			 if(listaBandas.size() > 0 && listaBandas!= null){
				 BigDecimal suma = BigDecimal.ZERO;
				 for(BandaProyeccionEntity ls : listaBandas){
					 suma = suma.add(ls.getPorcentaje());
					 bandas.add(suma);
				 }
			 }
		
			int i=0;
			for(BigDecimal ls :bandas ){
				
				++i;
				if(porcentaje.compareTo(ls) == -1){
					break;
				}
			}
			
			if(tipoColor ==1){
				switch(i){
				case 1:
					color = "C84545";
					break;
				case 2:
					color = "CFF30A";
					break;
				case 3:
					color = "02F327";
					break;
				}
			}
			
			if(tipoColor ==2){
				switch(i){
				case 1:
					color = "rojo";
					break;
				case 2:
					color = "amarillo";
					break;
				case 3:
					color = "verde";
					break;
				}
			}
			
			}catch(Exception e){
				System.out.println("Error en el proceso para capturar el color de la Banda - " + e);
				color="";
			}
			return color;
		}

	@Override
	public AvanceProyeccionProductResponse listaProductosCanal( String codTransaccion, FiltrosProyeccionCanalBean filtros) {
		
		String mensajeTransaccionMetodo = "[listaProductosCanal idTx=" + codTransaccion + "] - ";
		AvanceProyeccionProductResponse response = new AvanceProyeccionProductResponse();
		
		if(filtros.getIdPeriodo() < 1){
			System.out.println(mensajeTransaccionMetodo+" Es necesario el codigo del periodo");
			response.setIdTransaccion(codTransaccion);
			response.setCodigoRespuesta(ConstModAdministracion.MANT_LISTAR_COD_IDF);
			response.setMensajeRespuesta(ConstModAdministracion.MANT_LISTAR_MSJ_IDF.replace("msj", mensajeTransaccionMetodo));
			return response;
		}
		
		List<ProyeccionCatClienteDetEntity> listaProductoProyeccion = null;
		try{
			FiltrosSQLBean filtro = new FiltrosSQLBean();
			List<FiltrosBean> listaFiltros = new ArrayList<FiltrosBean>();
			List<Object> valores = new ArrayList<Object>();
			//filtro por periodo
			FiltrosBean filtroPeriodo = new FiltrosBean();
			List<String> campoPeriodo = new ArrayList<String>();
			campoPeriodo.add("pcc.periodo_id");
			filtroPeriodo.setCampos(campoPeriodo);
			filtroPeriodo.setOperador("=");
			listaFiltros.add(filtroPeriodo);
			valores.add(filtros.getIdPeriodo());
			
			if(filtros.getIdZona() > 0){
				//filtro por zona
				FiltrosBean filtroZona = new FiltrosBean();
				List<String> campoZona = new ArrayList<String>();
				campoZona.add("pcc.zona_id");
				filtroZona.setCampos(campoZona);
				filtroZona.setOperador("=");
				listaFiltros.add(filtroZona);
				valores.add(filtros.getIdZona());
			}
			if(filtros.getIdCanal() > 0){
				//filtro por canal
				FiltrosBean filtroCanal = new FiltrosBean();
				List<String> campoCanal = new ArrayList<String>();
				campoCanal.add("pcc.categoria_cliente_id");
				filtroCanal.setCampos(campoCanal);
				filtroCanal.setOperador("=");
				listaFiltros.add(filtroCanal);
				valores.add(filtros.getIdCanal());
			}
			filtro.setListaFiltros(listaFiltros);
			filtro.setListaValores(valores);
			filtro.setCampoOrden("p.producto");
			filtro.setTipoOrden("asc");
			//1.- obtenemos las proyeccion de productos por canal
			listaProductoProyeccion =mantProyeccionCatClienteDetDao.proyeccionCatClienteDetalle(filtro);
		}catch(Exception e){
			System.out.println(mensajeTransaccionMetodo + "Hubo un error al Tratar de obtener la proyeccion de los productos" +e);
			response.setCodigoRespuesta(ConstModAdministracion.MANT_LISTAR_COD_IDT);
			response.setMensajeRespuesta(ConstModAdministracion.MANT_LISTAR_MSJ_IDT.replace("msj", mensajeTransaccionMetodo));
			return response;
		}
		
		List<VentasEntity> ventasProducto =null;
		try{
			FiltrosSQLBean filtro = new FiltrosSQLBean();
			List<FiltrosBean> listaFiltros = new ArrayList<FiltrosBean>();
			List<Object> valores = new ArrayList<Object>();
			//filtro por periodo
			FiltrosBean filtroPeriodo = new FiltrosBean();
			List<String> campoPeriodo = new ArrayList<String>();
			campoPeriodo.add("periodo_id");
			filtroPeriodo.setCampos(campoPeriodo);
			filtroPeriodo.setOperador("=");
			listaFiltros.add(filtroPeriodo);
			valores.add(filtros.getIdPeriodo());
			
			if(filtros.getIdZona() > 0){
				//filtro por zona
				FiltrosBean filtroZona = new FiltrosBean();
				List<String> campoZona = new ArrayList<String>();
				campoZona.add("zona_id");
				filtroZona.setCampos(campoZona);
				filtroZona.setOperador("=");
				listaFiltros.add(filtroZona);
				valores.add(filtros.getIdZona());
			}
			if(filtros.getIdCanal() > 0){
				//filtro por canal
				FiltrosBean filtroCanal = new FiltrosBean();
				List<String> campoCanal = new ArrayList<String>();
				campoCanal.add("categoria_cliente_id");
				filtroCanal.setCampos(campoCanal);
				filtroCanal.setOperador("=");
				listaFiltros.add(filtroCanal);
				valores.add(filtros.getIdCanal());
			}
			filtro.setListaFiltros(listaFiltros);
			filtro.setListaValores(valores);
			filtro.setCampoOrden("producto_id");
			filtro.setTipoOrden("asc");
			//2.-obtenemos las ventas de los productos 
			ventasProducto =consultaVentasDao.listaVentasDetalle(filtro);
		}catch(Exception e){
			System.out.println(mensajeTransaccionMetodo + "Hubo un error al Tratar de obtener la ventas de los productos " +e.getMessage());
			response.setCodigoRespuesta(ConstModAdministracion.MANT_LISTAR_COD_IDT);
			response.setMensajeRespuesta(ConstModAdministracion.MANT_LISTAR_MSJ_IDT.replace("msj", mensajeTransaccionMetodo));
			return response;
		}
		List<AvanceVentaProductosBean> listaProductos = new ArrayList<AvanceVentaProductosBean>();
		//recorremos las proyeccion de los productos
		for(ProyeccionCatClienteDetEntity proyeccion :listaProductoProyeccion){
			AvanceVentaProductosBean bean = new AvanceVentaProductosBean();
			
			BigDecimal avanceProducto = BigDecimal.ZERO;
			for(VentasEntity ventas : ventasProducto){
				//capturamos las ventas por el codigo de producto
				if(proyeccion.getProducto_id()==ventas.getProducto_id()){
					avanceProducto = avanceProducto.add(ventas.getCantidad());
				}
			}
			
			BigDecimal porcentajeAvancePeriodo= BigDecimal.ZERO; 
			try{
				//calculamos el porcentaje de avance periodo
				porcentajeAvancePeriodo = avanceProducto.divide(proyeccion.getCantidad_proyectada(),4, RoundingMode.CEILING);
			}catch(Exception e){
				System.out.println("Error al calcular porcentaje - "+e );
				porcentajeAvancePeriodo= BigDecimal.ZERO; 
			}
			
			String color = colorBanda(validaciones.validarCamposString(proyeccion.getCodigo_banda()), porcentajeAvancePeriodo,2);
			
			bean.setAvancePorcentaje(porcentajeAvancePeriodo.multiply(new BigDecimal(100)));
			bean.setAvanceProducto(avanceProducto);
			bean.setCategoriaProducto(proyeccion.getCategoria_producto());
			bean.setCategoriaProductoId(proyeccion.getCategoria_producto_id());
			bean.setColorBanda(color);
			bean.setCodProd(validaciones.validarCamposString(proyeccion.getCod_prod()));
			bean.setId(proyeccion.getId());
			bean.setMarca(validaciones.validarCamposString(proyeccion.getMarca()));
			bean.setMarcaId(proyeccion.getMarca_id());
			bean.setPeriodoId(proyeccion.getPeriodo_id());
			bean.setProducto(validaciones.validarCamposString(proyeccion.getProducto()));
			bean.setProductoId(proyeccion.getProducto_id());
			bean.setProyeccionProducto(proyeccion.getCantidad_proyectada());
			bean.setZonaId(proyeccion.getZona_id());
			listaProductos.add(bean);
		}
		response.setIdTransaccion(codTransaccion);
		response.setCodigoRespuesta(ConstantesInternasSistema.CODIGO_EXITO);
		response.setMensajeRespuesta(ConstantesInternasSistema.MENSAJE_EXITO);
		response.setListaProductosZonas(listaProductos);
		return response;
	}
}
